package com.lyf.scm.plan.domain.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.lyf.scm.common.enums.OtherTargetsEnum;
import com.lyf.scm.common.enums.SkuUnitTypeEnum;
import com.lyf.scm.plan.api.dto.*;
import com.lyf.scm.plan.domain.remote.purchase.facade.PurchaseFacade;
import com.lyf.scm.plan.domain.service.ActualQtyService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * 实际到仓库
 *
 * @author wangchlei
 * @date 2020/11/24
 */
@Service
public class ActualQtyServiceImpl implements ActualQtyService {
    @Resource
    private PurchaseFacade purchaseFacade;

    @Override
    public OtherTargetResultDTO getResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO, Map<String, BigDecimal> unitMap) {
        List<PoQtyQueryDTO> poQtyQueryDTOS = otherTargetGeneralQueryDTO.getPoQtyQueryDTOS();
        List<String> dateList = otherTargetGeneralQueryDTO.getDateList();
        List<Date> dates = this.transferToDate(dateList);
        Long unitType = otherTargetGeneralQueryDTO.getUnitType();
        OtherTargetResultDTO otherTargetResultDTO = defultValue();
        if (CollectionUtils.isNotEmpty(poQtyQueryDTOS)) {
            List<PwQtyDTO> pwQtyDTOs;
            for (PoQtyQueryDTO poQtyQueryDTO : poQtyQueryDTOS) {
                pwQtyDTOs = purchaseFacade.qualifiedProductQty(poQtyQueryDTO);
                if (CollectionUtils.isNotEmpty(pwQtyDTOs)) {
                    //仓库+sku分组    按照日期填充集合
                    Map<String, List<BigDecimal>> resultMap = pwQtyDTOs.stream().collect(groupingBy(item -> item.getWarehouseCode() + item.getSkuCode(), Collectors.collectingAndThen(Collectors.toList(), values -> {
                        Map<Date, BigDecimal> subResultMap = values.stream().collect(groupingBy(element -> DateUtil.beginOfWeek(element.getWarehouseDate()), Collectors.collectingAndThen(Collectors.toList(), subValues -> {
                            BigDecimal b = BigDecimal.ZERO;
                            for (PwQtyDTO pwQtyDTO : subValues) {
                                if (pwQtyDTO.getQuantity() != null) {
                                    b = b.add(pwQtyDTO.getQuantity());
                                }
                            }
                            //单位
                            if (!SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType().equals(unitType)) {
                                String skuCode = subValues.get(0).getSkuCode();
                                BigDecimal scale = unitMap.get(skuCode + SkuUnitTypeEnum.PURCHASE_UNIT.getUnitType() + unitType);
                                return b.multiply(scale).setScale(3,BigDecimal.ROUND_HALF_UP);
                            } else {
                                return b;
                            }
                        })));
                        List<BigDecimal> l = new ArrayList<>();
                        for (Date date : dates) {
                            if (subResultMap.get(date) != null) {
                                l.add(subResultMap.get(date));
                            } else {
                                l.add(BigDecimal.ZERO);
                            }
                        }
                        return l;
                    })));
                    String key;
                    List<BigDecimal> value;
                    for (Map.Entry<String, List<BigDecimal>> item : resultMap.entrySet()) {
                        key = item.getKey();
                        value = item.getValue();
                        otherTargetResultDTO.getResult().put(key, value);
                    }
                }
            }
        }
        return otherTargetResultDTO;
    }

    private OtherTargetResultDTO defultValue() {
        OtherTargetResultDTO otherTargetResultDTO = new OtherTargetResultDTO();
        otherTargetResultDTO.setOtherTargetsEnum(OtherTargetsEnum.ACTUAL_QTY);
        Map<String, List<BigDecimal>> result = new HashMap<>();
        otherTargetResultDTO.setResult(result);
        return otherTargetResultDTO;
    }

    private List<Date> transferToDate(List<String> dateList) {
        List<Date> dates = new ArrayList<>();
        for (String dateStr : dateList) {
            dates.add(DateUtil.parse(dateStr, DatePattern.NORM_DATE_PATTERN));
        }
        return dates;
    }

    @Override
    public List<OtherTargetResultDTO> getBatchResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO, Map<String, BigDecimal> unitMap) {
        return null;
    }

    @Override
    public OtherTargetEchartResultDTO getEchartResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO) {
        PoQtyAggregationQueryDTO poQtyAggregationQueryDTO = otherTargetGeneralQueryDTO.getPoQtyAggregationQueryDTOs();
        List<String> dateList = otherTargetGeneralQueryDTO.getDateList();
        List<Date> dates = this.transferToDate(dateList);
        OtherTargetEchartResultDTO otherTargetEchartResultDTO = defultEchartValue();
        if (poQtyAggregationQueryDTO != null) {
            List<PwQtyDTO> pwQtyDTOs = purchaseFacade.aggregationQualifiedProductQty(poQtyAggregationQueryDTO);
            if (CollectionUtils.isNotEmpty(pwQtyDTOs)) {
                //仓库+sku分组    按照日期填充集合
                Map<Date, BigDecimal> subResultMap = pwQtyDTOs.stream().collect(groupingBy(element -> DateUtil.beginOfWeek(element.getWarehouseDate()), Collectors.collectingAndThen(Collectors.toList(), subValues -> {
                    BigDecimal b = BigDecimal.ZERO;
                    for (PwQtyDTO pwQtyDTO : subValues) {
                        if (pwQtyDTO.getQuantity() != null) {
                            b = b.add(pwQtyDTO.getQuantity());
                        }
                    }
                    return b;
                })));
                List<BigDecimal> l = new ArrayList<>();
                for (Date date : dates) {
                    if (subResultMap.get(date) != null) {
                        l.add(subResultMap.get(date));
                    } else {
                        l.add(BigDecimal.ZERO);
                    }
                }
                otherTargetEchartResultDTO.setResult(l);
            }
        }
        return otherTargetEchartResultDTO;
    }

    /**
     * 初始值
     *
     * @param
     * @return {@link List<OtherTargetResultDTO>}
     **/
    private OtherTargetEchartResultDTO defultEchartValue() {
        //赋初始值
        OtherTargetEchartResultDTO otherTargetResultDTO = new OtherTargetEchartResultDTO();
        otherTargetResultDTO.setOtherTargetsEnum(OtherTargetsEnum.ACTUAL_QTY);
        List<BigDecimal> result = new ArrayList<>();
        otherTargetResultDTO.setResult(result);
        return otherTargetResultDTO;
    }

    @Override
    public List<OtherTargetEchartResultDTO> getBatchEchartResult(OtherTargetGeneralQueryDTO otherTargetGeneralQueryDTO) {
        return null;
    }
}
